home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mntlb20 / lib / _fxunsd.cpp < prev    next >
C/C++ Source or Header  |  1992-03-30  |  3KB  |  171 lines

  1. |
  2. | double float to unsigned long conversion routine
  3. | does not really return unsigned long: max result is 0x7fffffff
  4. | mjr
  5.     .text
  6.     .even
  7.  
  8. #ifdef ERROR_CHECK
  9.  
  10. _Overflow:
  11.     .ascii "OVERFLOW\0"
  12. _Negative:
  13.     .ascii "NEGATIVE NUMBER\0"
  14. _Error_String:
  15.     .ascii "_fixunsdfsi: %s error\n\0"
  16. .even
  17.  
  18. #endif ERROR_CHECK
  19.  
  20. #ifdef __M68881__
  21.  
  22.     .globl    __fixunsdfsi, ___fixunsdfsi
  23.  
  24. __fixunsdfsi:
  25. ___fixunsdfsi:
  26.  
  27.     fintrzd a7@(4),fp0        | convert
  28.     fmovel    fp0,d0
  29.  
  30. #endif __M68881__
  31.  
  32. #ifdef    sfp004
  33. | double float to unsigned long conversion routine
  34. | does not really return unsigned long: max result is 0x7fffffff
  35. | mjr
  36.  
  37. comm =     -6
  38. resp =    -16
  39. zahl =      0
  40.  
  41.     .text
  42.     .even
  43.     .globl    __fixunsdfsi, ___fixunsdfsi
  44.  
  45. __fixunsdfsi:
  46. ___fixunsdfsi:
  47.     lea    0xfffa50,a0
  48.     tstl    a4@(4)            | negative?
  49.     bne    Negative
  50.     movew    #0x5403,a0@(comm)    | fintrz to fp0
  51.     cmpiw    #0x8900,a0@(resp)    | check
  52.     movel    a7@(4),a0@
  53.     movel    a7@(8),a0@
  54.     movew    #0x6000,a0@(comm)    | result to d0
  55.     .long    0x0c688900, 0xfff067f8
  56.     movel    a0@,d0
  57.     bra    Continue
  58. Negative:
  59.     clrl    d0
  60. Continue:
  61. # endif    sfp004
  62.  
  63. # ifdef    ERROR_CHECK
  64.     cmpil    #0x7fffffff,d0    | >= long_max
  65.     bge    error_plus    |
  66.     cmpil    #0,d0        | < 0 ?
  67.     blt    error_minus    |
  68.     rts            |
  69. error_minus:
  70.     moveml    d0-d1,a7@-
  71.     movel    #63,_errno    | errno = ERANGE
  72.     pea    _Negative    | for printf
  73.     bra    error_exit    |
  74. error_plus:
  75.     moveml    d0-d1,a7@-
  76.     movel    #63,_errno    | errno = ERANGE
  77.     pea    _Overflow    | for printf
  78.     bra    error_exit    |
  79. error_exit:
  80.     pea    _Error_String    |
  81.     pea    __iob+52    |
  82.     jbsr    _fprintf    |
  83.     addl    #12,a7        |
  84.     moveml    a7@+,d0-d1
  85.     rts
  86. # else     ERROR_CHECK
  87.     rts
  88. # endif    ERROR_CHECK
  89.  
  90. # if !defined (sfp004) && !defined (__M68881__)
  91.  
  92. | double float to unsigned long conversion routine
  93. |
  94. | written by Kai-Uwe Bloem (I5110401@dbstu1.bitnet).
  95. | Based on a 80x86 floating point packet from comp.os.minix, written by P.Housel
  96. |
  97. |
  98. | Revision 1.3, kub 01-90 :
  99. | added support for denormalized numbers
  100. |
  101. | Revision 1.2, kub 01-90 :
  102. | replace far shifts by swaps to gain speed
  103. |
  104. | Revision 1.1, kub 12-89 :
  105. | Ported over to 68k assembler
  106. |
  107. | Revision 1.0:
  108. | original 8088 code from P.S.Housel
  109.  
  110. BIAS8    =    0x3FF-1
  111.  
  112.     .text
  113.     .even
  114.     .globl    __fixunsdfsi, ___fixunsdfsi
  115.  
  116. __fixunsdfsi:
  117. ___fixunsdfsi:
  118.     lea    sp@(4),a0    | pointer to parameters
  119.     moveml    d4/d5,sp@-    | save registers
  120.     moveml    a0@,d4-d5    | get the number
  121.     movew    a0@,d0        | extract exp
  122.     lsrw    #4,d0
  123.     andw    #0x07ff,d0    | kill sign bit
  124.  
  125.     andl    #0x0fffff,d4    | remove exponent from mantissa
  126.     orl    #0x100000,d4    | restore implied leading "1"
  127.  
  128.     cmpw    #BIAS8,d0    | check exponent
  129.     blt    zero        | strictly factional, no integer part ?
  130.     cmpw    #BIAS8+32,d0    | is it too big to fit in a 32-bit integer ?
  131.     bgt    toobig
  132.  
  133.     subw    #BIAS8+21,d0    | adjust exponent
  134.     bgt    2f        | shift up
  135.     beq    3f        | no shift
  136.  
  137.     cmpw    #-8,d0        | replace far shifts by swap
  138.     bgt    1f
  139.     movew    d4,d5        | shift fast, 16 bits
  140.     swap    d5
  141.     clrw    d4
  142.     swap    d4
  143.     addw    #16,d0        | account for swap
  144.     bgt    2f
  145.     beq    3f
  146.  
  147. 1:    lsrl    #1,d4        | shift down to align radix point;
  148.     addw    #1,d0        | extra bits fall off the end (no rounding)
  149.     blt    1b        | shifted all the way down yet ?
  150.     bra    3f
  151.  
  152. 2:    addl    d5,d5        | shift up to align radix point
  153.     addxl    d4,d4
  154.     subw    #1,d0
  155.     bgt    2b
  156. 3:
  157.     movel    d4,d0        | put integer into result register
  158. 7:
  159.     moveml    sp@+,d4/d5
  160.     rts
  161.  
  162. zero:
  163.     clrl    d0        | make the whole thing zero
  164.     bra    7b
  165.  
  166. toobig:
  167.     movel    #0x7fffffff,d0    | ugh. Should cause a trap here.
  168.     bra    7b
  169.  
  170. #endif
  171.